<template>
  <el-upload
    class="image-uploader"
    :class="{ 'is-limit': files.length === limit }"
    action
    :file-list="files"
    list-type="picture-card"
    :http-request="doUpload"
    :on-remove="onRemove"
    :on-preview="handlePreview"
    :on-exceed="onExceed"
    :multiple="limit !== 1"
    :limit="limit"
    :disabled="$attrs.readonly"
    v-bind="$attrs"
  >
    <el-icon class="uploader-icon">
      <plus />
    </el-icon>
  </el-upload>
  <el-dialog width="30%" :model-value="!!isPreview" @close="isPreview = ''">
    <img style="width: 100%" :src="isPreview" alt="不支持的格式" />
  </el-dialog>
</template>

<script>
  import { Plus } from '@element-plus/icons-vue'
  import { computed, nextTick, ref, toRefs, watch } from 'vue'
  import request from '@/utils/request'
  import { ElMessage } from 'element-plus'

  function uploadImg(file) {
    let fd = new FormData()
    fd.append('file', file)
    // console.log(file)
    return request({
      url: '/smart/file/upload',
      method: 'post',
      headers: {
        'Content-Type': 'multipart/form-data',
      },
      data: fd,
    })
  }

  export default {
    name: 'FileUploader',
    components: { Plus },
    props: {
      modelValue: [String, Array],
    },
    emits: ['deleteFile'],
    setup(props, { emit }) {
      const files = ref([])
      const myfiles = ref([])

      let type,
        enableRender = true
      const initFiles = () => {
        const val = props.modelValue
        type = Array.isArray(val) ? 'array' : 'string'
        files.value = []
        if (val) {
          if (type === 'string') {
            files.value.push({ name: 0, url: val })
          }
          if (type === 'array') {
            myfiles.value = val.map(v => ({ name: '', url: v, uid: v }))
            files.value = val.map(v => ({ name: '', url: v, uid: v }))
          }
        }
      }
      const emitValue = async (file, data) => {
        enableRender = false
        if (data.url) {
          if (type === 'string') {
            // console.log(files.value[0]);
            // emit("update:modelValue", files.value[0]?.url || "");
            emit('update:modelValue', data.url || '')
          }
          if (type === 'array') {
            if (!myfiles.value.includes(data.url))
              myfiles.value.push({
                url: data.url,
                uid: file.uid,
              })
            emit(
              'update:modelValue',
              // files.value.map(v => v.url)
              myfiles.value.map(v => v.url)
            )
          }
        }
        await nextTick()
        enableRender = true
      }
      initFiles()
      const { modelValue } = toRefs(props)
      watch(modelValue, v => {
        // console.log(v)
        if (v === undefined || (type === 'array' && v.length === 0)) {
          files.value = []
        }
        else if (enableRender) {
          initFiles()
        }
      })
      const doUpload = async ({ file }) => {
        const { data } = await uploadImg(file)
        // console.log(data,"asda");
        await emitValue(file, data)
        return Promise.resolve()
      }
      const onRemove = (removeTargetFile, removedFiles) => {
        emit('deleteFile', removeTargetFile)
        //  console.log(myfiles.value)
        const idx = myfiles.value.findIndex(v => v.uid === removeTargetFile.uid)
        if (idx !== -1) myfiles.value.splice(idx, 1)
        emit(
          'update:modelValue',
          myfiles.value.map(v => v.url)
        )
        files.value = removedFiles

        // emitValue();
      }
      const onExceed = (_, files) => {
        ElMessage.warning(`你最多只能上传 ${files.length} 个文件`)
      }
      const isPreview = ref(false)
      const handlePreview = e => {
        isPreview.value = e.url
      }

      return {
        files,
        limit: computed(() => (Array.isArray(props.modelValue) ? 9 : 1)),
        handlePreview,
        doUpload,
        isPreview,
        onRemove,
        onExceed,
      }
    },
  }
</script>

<style scoped lang="scss">
  .image-uploader :deep(.el-upload) {
    border: 1px dashed #b7abab;
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
  }

  .image-uploader .el-upload:hover {
    border-color: #409eff;
  }

  .is-limit {
    :deep(.el-upload) {
      display: none;
    }
  }
</style>
